package com.xingchi.tornado.security.service;

import com.xingchi.tornado.security.enums.LoginTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.Authentication;

import java.util.ArrayList;
import java.util.List;

/**
 * 登录类型管理器
 *
 * @author xiaoya
 * @date 2025/7/21 17:04
 */
@Slf4j
public final class LoginTypeManager {

    public static final List<LoginTypeService> LOGIN_TYPE_SERVICE_LIST;

    static {
        LOGIN_TYPE_SERVICE_LIST = new ArrayList<>();
        LoginTypeEnum[] values = LoginTypeEnum.values();
        for (LoginTypeEnum value : values) {
            LoginTypeService loginTypeService = LoginTypeService.build(value.getDesc(), value.getCode(), value.getClazz());
            LOGIN_TYPE_SERVICE_LIST.add(loginTypeService);
        }
    }

    private LoginTypeManager() {
        throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
    }

    public static LoginTypeService getLoginTypeService(Integer code) {
        for (LoginTypeService loginTypeService : LOGIN_TYPE_SERVICE_LIST) {
            if (loginTypeService.supports(code)) {
                return loginTypeService;
            }
        }
        log.warn("登录类型不支持，类型：{}", code);
        throw new IllegalArgumentException("登录类型不支持");
    }

    public static boolean add(String name, Integer code, Class<? extends Authentication> authenticationClass) {
        return add(LoginTypeService.build(name, code, authenticationClass));
    }

    public static LoginTypeService getInstance(Integer code) {
        return getLoginTypeService(code);
    }

    public static boolean add(LoginTypeService loginTypeService) {

        synchronized (LOGIN_TYPE_SERVICE_LIST) {
            Integer code = loginTypeService.getCode();
            boolean exists = LOGIN_TYPE_SERVICE_LIST.stream().anyMatch(loginTypeService1 -> loginTypeService1.supports(code));
            if (exists) {
                log.error("登录类型已存在，类型：{}", code);
                throw new IllegalArgumentException(String.format("登录类型已存在 %s", code));
            }
            return LOGIN_TYPE_SERVICE_LIST.add(loginTypeService);
        }
    }

    public static boolean remove(Integer code) {

        synchronized (LOGIN_TYPE_SERVICE_LIST) {
            return LOGIN_TYPE_SERVICE_LIST.removeIf(loginTypeService -> loginTypeService.supports(code));
        }
    }

    public static void prettyPrint() {
        StringBuilder sb = new StringBuilder();
        sb.append("\n");
        sb.append(StringUtils.repeat("=", 80)).append("\n");
        sb.append("\t\t\t登录类型，共计 ").append(LOGIN_TYPE_SERVICE_LIST.size()).append(" 种\n");
        LOGIN_TYPE_SERVICE_LIST.forEach(loginSourceService ->  sb.append("\t\t\t\t").append(loginSourceService.getName())
                .append(":")
                .append(loginSourceService.getCode())
                .append(":")
                .append(loginSourceService.getAuthenticationClass().getName())
                .append("\n"));
        sb.append(StringUtils.repeat("=", 80)).append("\n");
        log.info(sb.toString());
    }

}
